package com.xmhmyh.generalframework.common.wxutils.Handlers;

import com.alibaba.fastjson.JSONObject;
import com.xmhmyh.generalframework.common.wxutils.entity.*;
import com.xmhmyh.generalframework.common.wxutils.util.HttpUtil;
import com.xmhmyh.generalframework.common.wxutils.util.PaymentKit;
import com.xmhmyh.generalframework.common.wxutils.util.WxUrl;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * @Author: 于丁
 * 微信用户相关处理
 * @DateTime: 2020/4/20 1:59 下午
 */
public class WxPayHandler extends WxHandler {


    /**
     * @Author: 于丁
     * @Description: 支付成功返回微信的信息
     * @DateTime: 2020/5/27 2:11 下午
     * @Params:
     * @Return
     */
    public static final String SUCCESSBACK = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

    /**
     * @Author: 于丁
     * @Description: 获取H5支付参数
     * @DateTime: 2020/4/21 10:34 上午
     * @Params:
     * @Return
     */
    public WxH5PayResult placeH5PayOrder(WxH5PayParams wxH5PayParams) {
        WxH5PayResult wxH5PayResult = new WxH5PayResult();
        Map<String, String> params = new HashMap<String, String>();
        // 拼接微信参数
        params.put("appid", wxH5PayParams.getAppId());
        params.put("mch_id", wxH5PayParams.getMchId());
        params.put("body", wxH5PayParams.getBody());
        params.put("out_trade_no", wxH5PayParams.getOutTradeNo());
        params.put("total_fee", wxH5PayParams.getTotalFee());
        params.put("trade_type", "MWEB");
        params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
        params.put("notify_url", wxH5PayParams.getNotifyUrl());
        // 签名
        String sign = PaymentKit.createSign(params, wxH5PayParams.getApiKey());
        params.put("sign", sign);
        String xmlResult = HttpUtil.wxRequest(WxUrl.UNIFIEDORDERURL, "POST", PaymentKit.toXml(params));
        Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
        String returnCode = result.get("return_code");
        if (returnCode.equals("SUCCESS")) {
            String resultCode = result.get("result_code");
            if (resultCode.equals("SUCCESS")) {
                wxH5PayResult.setPrepay_id(result.get("prepay_id"));
                wxH5PayResult.setMweb_url(result.get("mweb_url"));
                wxH5PayResult.setTrade_type(result.get("trade_type"));
            } else {
                wxH5PayResult.setErrorMsg("errorCode:" + result.get("err_code") + "===errorMsg:" + result.get("err_code_des"));
            }
        } else {
            wxH5PayResult.setErrorMsg(result.get("return_msg"));
        }
        return wxH5PayResult;
    }


    /**
     * @Author: 于丁
     * @Description: 获取JsApi支付参数
     * @DateTime: 2020/4/21 2:30 下午
     * @Params:
     * @Return
     */
    public WxPayResult placeJsApiPayParams(WxJsApiPayParams wxJsApiPayParams){
        //拼接微信支付参数
        WxPayResult wxPayResult = new WxPayResult();
        Map<String, String> params = new HashMap<String, String>();
        params.put("appid", wxJsApiPayParams.getAppId());
        params.put("mch_id", wxJsApiPayParams.getMchId());
        params.put("body", wxJsApiPayParams.getBody());
        params.put("out_trade_no", wxJsApiPayParams.getOutTradeNo());
        params.put("total_fee", wxJsApiPayParams.getTotalFee());
        params.put("trade_type", "JSAPI");
        params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
        params.put("notify_url", wxJsApiPayParams.getNotifyUrl());
        params.put("openid", wxJsApiPayParams.getOpenId());
        String sign = PaymentKit.createSign(params, wxJsApiPayParams.getApiKey());
        params.put("sign", sign);
        String xmlResult = HttpUtil.wxRequest(WxUrl.UNIFIEDORDERURL, "POST", PaymentKit.toXml(params));
        Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
        String returnCode = result.get("return_code");
        if (returnCode.equals("SUCCESS")) {
            String resultCode = result.get("result_code");
            if (resultCode.equals("SUCCESS")) {
                wxPayResult.setAppId(wxJsApiPayParams.getAppId());
                wxPayResult.setTimeStamp(System.currentTimeMillis() / 1000 + "");
                wxPayResult.setNonceStr(System.currentTimeMillis() + "");
                wxPayResult.setPackageStr("prepay_id=" + result.get("prepay_id"));
                wxPayResult.setSignType("MD5");
                //签名
                Map<String, String> packageParams = new HashMap<String, String>();
                packageParams.put("appId", wxJsApiPayParams.getAppId());
                packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
                packageParams.put("nonceStr", System.currentTimeMillis() + "");
                packageParams.put("package", "prepay_id=" + result.get("prepay_id"));
                packageParams.put("signType", "MD5");
                String packageSign = PaymentKit.createSign(packageParams, wxJsApiPayParams.getApiKey());
                wxPayResult.setPaySign(packageSign);
            } else {
                wxPayResult.setErrorMsg("errorCode:" + result.get("err_code") + "===errorMsg:" + result.get("err_code_des"));
            }
        } else {
            wxPayResult.setErrorMsg(result.get("return_msg"));
        }
        return wxPayResult;
    }


    /**
     * @Author: 于丁
     * @Description: 申请退款
     * @DateTime: 2020/4/21 11:09 上午
     * @Params:
     * @Return
     */
    public WxRefundResult refund(WxRefundParams wxRefundParams) {
        WxRefundResult wxRefundResult = new WxRefundResult();
        SortedMap<String, String> params = new TreeMap<String, String>();
        params.put("appid", wxRefundParams.getAppId());
        params.put("mch_id", wxRefundParams.getMchId());
        params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
        params.put("out_trade_no", wxRefundParams.getOutTradeNo());
        params.put("out_refund_no", wxRefundParams.getOutRefundNo());
        params.put("total_fee", wxRefundParams.getTotalFee());
        params.put("refund_fee", wxRefundParams.getRefundFee());
        String sign = PaymentKit.createSign(params, wxRefundParams.getApiKey());
        params.put("sign", sign);
        String xmlResult = HttpUtil.wxRequest(WxUrl.REFUNDURL, "POST", PaymentKit.toXml(params), wxRefundParams.getMchId(), wxRefundParams.getKeyStoryPath());
        Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
        String returnCode = result.get("return_code");
        if (returnCode.equals("SUCCESS")) {
            String resultCode = result.get("result_code");
            if (resultCode.equals("SUCCESS")) {
                wxRefundResult.setTransactionId(result.get("transaction_id"));
                wxRefundResult.setOutTradeNo(result.get("out_trade_no"));
                wxRefundResult.setOutRefundNo(result.get("out_refund_no"));
                wxRefundResult.setRefundId(result.get("refund_id"));
                wxRefundResult.setRefundFee(result.get("refund_fee"));
            } else {
                wxRefundResult.setErrorMsg("errorCode:" + result.get("err_code") + "===errorMsg:" + result.get("err_code_des"));
            }
        } else {
            wxRefundResult.setErrorMsg(result.get("return_msg"));
        }
        return wxRefundResult;
    }


    /**
     * @Author: 于丁
     * @Description: 获取支付回调参数
     * @DateTime: 2020/4/21 1:56 下午
     * @Params:
     * @Return
     */
    public WxPayBackResult getPayBackResult(HttpServletRequest httpServletRequest) throws IOException {
        InputStream inputStream = httpServletRequest.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while (true) {
            if (!((len = inputStream.read(buffer)) != -1)) {
                break;
            }
            outSteam.write(buffer, 0, len);
        }
        String resultxml = new String(outSteam.toByteArray(), "utf-8");
        Map<String, String> params = PaymentKit.xmlToMap(resultxml);
        WxPayBackResult wxPayBackResult = new WxPayBackResult();
        wxPayBackResult = JSONObject.parseObject(JSONObject.toJSONString(params), WxPayBackResult.class);
        wxPayBackResult.setReturn_code(params.get("return_code"));
        wxPayBackResult.setReturn_msg(params.get("return_msg"));
        wxPayBackResult.setSign(params.get("sign"));
        wxPayBackResult.setOut_trade_no(params.get("out_trade_no"));
        wxPayBackResult.setParams(params);
        inputStream.close();
        return wxPayBackResult;
    }

    /**
     * @Author: 于丁
     * @Description: 检查微信支付回调签名
     * @DateTime: 2020/4/21 2:01 下午
     * @Params:
     * @Return
     */
    public Boolean checkWxPayBackSign(WxPayBackResult wxPayBackResult, String apiKey) {
        if (wxPayBackResult.getResult_code().equals("SUCCESS")) {
            String my_sign = PaymentKit.createSign(wxPayBackResult.getParams(), apiKey);
            if (!my_sign.equals(wxPayBackResult.getSign())) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    }
}
